package com.thymeleaf.demo.util;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 公共方法
@Component
public class Common {

    // 获取md5加密后的信息
    // 获取随机数
    // 加密算法
    // 结算法

    /**
     * 获取10位数的时间戳（精确到秒）
     * @return
     */
    public static int getCurrent(){
        Date date = new Date();
        String timestamp = String.valueOf(date.getTime()/1000);
        return Integer.parseInt(timestamp);
    }

    //封装sql查询方法，返回RowMapper对象
    public<T> RowMapper<T> createJDBCSql(Class<T> classes){
        return new RowMapper<T>() {
            @Override
            public T mapRow(ResultSet rs, int index) throws SQLException {
                T item = null;
                try {
                    item = classes.getDeclaredConstructor().newInstance();
                    // 获取列名的对象
                    ResultSetMetaData metaData = rs.getMetaData();
                    // 通过for循环来设置类对象的成员属性值
                    for(int i = 1; i <= metaData.getColumnCount(); i++){
                        // 获取列名(并且下划线转驼峰)
                        String columnName = lineToHump(metaData.getColumnLabel(i));
                        // 获取列值
                        Object columnValue = rs.getObject(i);
                        // 设置成员属性值
                        Field field = classes.getDeclaredField(columnName);
                        field.setAccessible(true);
                        field.set(item, columnValue);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return item;
            }
        };
    }

    //md5加密
    public String md5(String str){
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");

            char[] charArray = str.toCharArray();
            byte[] byteArray = new byte[charArray.length];

            for(int i = 0; i < charArray.length; i++){
                byteArray[i] = (byte) charArray[i];
            }

            byte[] md5Bytes = md5.digest(byteArray);

            StringBuilder builder = new StringBuilder();
            for(int i = 0; i < md5Bytes.length; i++){
                int val = ((int)md5Bytes[i]) & 0xff;
                if(val < 16){
                    builder.append(0);
                }
                builder.append(Integer.toHexString(val));
            }

            return builder.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 获取随机数

    /**
     *
     * @param length 随机的长度
     * @param type 随机的内容
     * @return 随机数
     */
    public String getRandomString(int length, int type){
        String base = "";
        switch (type){
            case 1:
                base = "abcdefghijklmnopqrstuvwxyz";
                break;
            case 2:
                base = "1234567890";
                break;
            default:
                base = "abcdefghijklmnopqrstuvwxyz1234567890";
                break;
        }
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < length; i++){
            int num = random.nextInt(base.length());
            stringBuilder.append(base.charAt(num));
        }
        return stringBuilder.toString();
    }

    /**
     * 下划线转驼峰
     * @param str
     * @return
     */
    public String lineToHump(String str) {
        // 匹配一个下划线加一个字符
        Pattern linePattern = Pattern.compile("_(\\w)");
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        // student_no
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }

        //appendTail方法：sb是一个StringBuffer，这个方法是把最后一次匹配到内容之后的字符串追加到StringBuffer中。
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 获取ip地址
     * @return
     */
    public static String getIpAddress(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
            ip = request.getRemoteAddr();
            if(ip.equalsIgnoreCase("127.0.0.1")){
                // 根据网卡再获取一下ip
                try {
                    InetAddress inet = InetAddress.getLocalHost();
                    ip = inet.getHostAddress();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }
        return ip;
    }

    /**
     * 创建uuid
     * @return uuid
     */
    public String createUUid(){
        // 直接获取的uuid，是带有 - 的，可以将-去掉
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
}
